package damas.ReglasDeAvances;

import java.util.LinkedList;
import java.util.List;

import utils.Pair;
import damas.modelo.DamasEstado;
import framework.IRule;

/**
 * @author Sin codigo Esta regla de avance, avanza comiendo hacia arriba, tanto
 *         para izquierda como para derecha, siempre que sea posible
 * 
 */
public class AvanzaComiendoHaciaArriba implements IRule<DamasEstado> {

	@Override
	public boolean isApplicable(DamasEstado estado) {
		return (estado.isMax() && !estado.getRojasDamasObligadasAComer()
				.isEmpty())
				|| (estado.isMin() && (!estado.getNegrasDamasObligadasAComer()
						.isEmpty() || !estado.getNegrasObligadasAComer()
						.isEmpty()));
	}

	// ya se que tengo alguna en la lista de obligadas a comer
	@Override
	public List<DamasEstado> apply(DamasEstado estado) {
		LinkedList<DamasEstado> newEstados = new LinkedList<DamasEstado>();
		int miColor = estado.isMax() ? estado.ROJA : estado.NEGRA;
		LinkedList<Pair<Integer, Integer>> obligadasAComer = new LinkedList<Pair<Integer, Integer>>();

		Pair<Integer, Integer> avArribaIzq;
		Pair<Integer, Integer> avArribaDer;
		int y;
		int x;
		// cargo mi lista de fichas a mover
		if (miColor == estado.ROJA) {
			if (estado.genereMovidaObligatoria) {
				obligadasAComer.add(estado.inicioObligatorio);
			} else {

				obligadasAComer = (LinkedList<Pair<Integer, Integer>>) estado
						.getRojasDamasObligadasAComer();
			}
		} else {
			if (estado.genereMovidaObligatoria) {
				obligadasAComer.add(estado.inicioObligatorio);
			} else {

				obligadasAComer = (LinkedList<Pair<Integer, Integer>>) estado
						.getNegrasDamasObligadasAComer();
				obligadasAComer.addAll(estado.getNegrasObligadasAComer());
			}
		}
		boolean useElClon = false;
		for (Pair<Integer, Integer> pair : obligadasAComer) {
			DamasEstado newEstado = estado.clone();
			y = pair.getFirstElem();
			x = pair.getSecondElem();
			avArribaDer = new Pair<Integer, Integer>(y - 2, x + 2);
			avArribaIzq = new Pair<Integer, Integer>(y - 2, x - 2);

			// la casilla esta en el tablero && tengo para comer
			if (newEstado.esCasillaValida(avArribaDer)
					&& !newEstado.hayFichaEnLaCasilla(avArribaDer)
					&& newEstado.esPosibleComerArribaDer(pair, avArribaDer,
							miColor)) {
				newEstado.mover(pair, avArribaDer);
				newEstado.genereMovidaObligatoria = newEstado
						.tieneComidaAlcanzable(avArribaDer);
				if (miColor == estado.ROJA) {
					newEstado.rojaComioEncadenada = newEstado.genereMovidaObligatoria;
				} else {
					newEstado.negraComioEncadenada = newEstado.genereMovidaObligatoria;
				}
				// obliga a usar esta pos para el proximo movimiento
				if (newEstado.genereMovidaObligatoria) {
					newEstado.inicioObligatorio = avArribaDer;
				}
				newEstados.add(newEstado);// meto el nuevo estado
				useElClon = true;
			}

			if (useElClon) {
				newEstado = estado.clone();
			}
			// la casilla esta en el tablero && tengo para comer
			if (newEstado.esCasillaValida(avArribaIzq)
					&& !newEstado.hayFichaEnLaCasilla(avArribaIzq)
					&& newEstado.esPosibleComerArribaIzq(pair, avArribaIzq,
							miColor)) {
				newEstado.mover(pair, avArribaIzq);
				newEstado.genereMovidaObligatoria = newEstado
						.tieneComidaAlcanzable(avArribaIzq);
				if (miColor == estado.ROJA) {
					newEstado.rojaComioEncadenada = newEstado.genereMovidaObligatoria;
				} else {
					newEstado.negraComioEncadenada = newEstado.genereMovidaObligatoria;
				}
				if (newEstado.genereMovidaObligatoria) {
					newEstado.inicioObligatorio = avArribaIzq;
				}
				newEstados.add(newEstado);// meto el nuevo estado
			}
		}// end for

		return newEstados;
	}
}
